<template>
  <el-container class="upload-page">
    <!-- 验证码输入部分 -->
    <div v-if="!isVerified" class="verify-section">
      <h3>请输入验证码</h3>
      <el-input v-model="code" placeholder="请输入验证码" style="width: 100%;" />
      <el-button 
        type="primary" 
        style="width: 100%; margin-top: 10px;" 
        @click="submitCode"
      >
        提交
      </el-button>
    </div>

    <!-- 已验证内容区域 -->
    <div v-else class="verified-content">
      <div class="expire-time">有效期至 {{ formattedExpireTime }}</div>

      <div class="button-group">
        <el-button type="primary" @click="$refs.fileInput.click()">上传图片</el-button>
        <el-button type="success" @click="submitOrder">提交订单</el-button>
        <input 
          ref="fileInput" 
          type="file" 
          multiple 
          accept="image/*" 
          @change="handleFileChange" 
          hidden 
        />
      </div>

      <div v-if="images.length > 0" class="image-list-container">
        <el-row :gutter="20" class="image-list">
          <el-col
            v-for="(img, index) in images"
            :key="index"
            :xs="24" 
            :sm="12" 
            :md="8" 
            :lg="6"
            :xl="6"
            class="image-col"
          >
            <div class="image-item">
              <img 
                :src="getImageUrl(img.id)" 
                alt="preview" 
                class="preview-img"
                crossorigin="anonymous" 
              />
              <div style="display: flex; justify-content: space-between; margin-top: 5px; width: 100%;">
                <el-button 
                  size="mini" 
                  style="flex: 1; border-radius: 4px;"
                  @click="editImage(img)"
                >
                  编辑
                </el-button>
                <el-button 
                  size="mini" 
                  type="danger"
                  style="flex: 1; margin-left: 5px; border-radius: 4px;"
                  @click="deleteImage(img)"
                >
                  删除
                </el-button>
              </div>
            </div>
          </el-col>
          <!-- 添加空占位符以确保网格布局 -->
          <el-col
            v-for="n in (4 - (images.length % 4))"
            :key="'placeholder-' + n"
            :xs="24" 
            :sm="12" 
            :md="8" 
            :lg="6"
            :xl="6"
            class="image-col placeholder"
          ></el-col>
        </el-row>
      </div>
      <div v-else class="empty-container">
        <el-empty :image-size="200"></el-empty>
      </div>
    </div>

    <!-- 裁剪弹窗 -->
    <el-dialog
      :visible.sync="cropperVisible"
      :title="'图片裁剪'"
      :width="isMobile ? '100%' : '70%'"
      :fullscreen="isMobile"
      @opened="handleDialogOpened"
      @closed="handleDialogClosed"
    >
      <div class="cropper-container">
        <vue-cropper
          ref="cropper"
          :img="cropperImageSrc"
          :auto-crop="true"
          :view-mode="1"
          :guides="true"
          :background="false"
          drag-mode="crop"
          :responsive="true"
          :auto-crop-area="0.8"
          :check-cross-origin="false"
          :rotatable="true"
          class="cropper-instance"
        ></vue-cropper>
      </div>
      <div slot="footer" class="dialog-footer">
        <el-button-group>
          <el-button @click="rotate(-45)" icon="el-icon-refresh-left">左转</el-button>
          <el-button @click="rotate(45)" icon="el-icon-refresh-right">右转</el-button>
          <el-button @click="zoom(0.1)" icon="el-icon-zoom-in">放大</el-button>
          <el-button @click="zoom(-0.1)" icon="el-icon-zoom-out">缩小</el-button>
        </el-button-group>
        <el-button 
          type="primary" 
          @click="cropAndUpload"
          :loading="isCropping"
        >
          {{ isCropping ? '处理中...' : '确认裁剪' }}
        </el-button>
      </div>
    </el-dialog>
  </el-container>
</template>

<script>
import axios from 'axios';
import { VueCropper } from 'vue-cropper';

export default {
  name: 'UploadImagePage',
  components: { VueCropper },
  data() {
    return {
      code: '',
      isVerified: false,
      verificationId: null,
      expireAt: null,
      images: [],
      cropperVisible: false,
      cropperImageSrc: null,
      currentImage: null,
      isMobile: false,
      isCropping: false,
      originalImage: null,
      currentShape: 'circle',
    };
  },
  computed: {
    formattedExpireTime() {
      if (!this.expireAt) return '';
      const date = new Date(this.expireAt);
      return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')} ${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}`;
    }
  },
  methods: {
    getImageUrl(imgId) {
      return `/api/user/minio/getImage/${imgId}?t=${Date.now()}_${Math.random().toString(36).substr(2, 5)}`;
    },

    // 编辑方法
    async editImage(image) {
      try {
        this.currentImage = image;
        this.originalImage = { ...image };
        
        // 使用原生XHR确保可靠加载
        const blob = await new Promise((resolve, reject) => {
          const xhr = new XMLHttpRequest();
          xhr.open('GET', this.getImageUrl(image.id), true);
          xhr.responseType = 'blob';
          xhr.onload = () => {
            if (xhr.status === 200) resolve(xhr.response);
            else reject(new Error(`图片加载失败: ${xhr.status}`));
          };
          xhr.onerror = () => reject(new Error('网络错误'));
          xhr.send();
        });
        
        this.cropperImageSrc = URL.createObjectURL(blob);
        this.cropperVisible = true;
      } catch (error) {
        this.$loading().close();
        console.error('图片加载失败:', error);
        this.$message.error('图片加载失败: ' + error.message);
      }
    },

    // 初始化方法
    initCropper() {
      const cropper = this.$refs.cropper;

      if (!cropper) {
        console.warn('裁剪组件未加载');
        this.$message.error('裁剪组件加载失败，请刷新重试');
        return;
      }

      this.$nextTick(() => {
        try {
          // 确保 cropper.init 被正确调用
          if (typeof cropper.init !== 'function') {
            throw new Error('裁剪器实例不存在 init 方法');
          }

          cropper.init({
            aspectRatio: this.aspectRatio || 1, // 设置默认值
            viewMode: 1,
            autoCropArea: 0.8,
            guides: true,
            background: false
          });
          console.log('裁剪器初始化成功，当前比例:', this.aspectRatio);
        } catch (error) {
          console.error('裁剪器初始化失败:', error);
          // 只有当确实遇到无法恢复的错误时才显示错误消息
          if (!this.cropperImageSrc) {
            this.$message.error('裁剪器初始化失败');
          }
        }
      });
    },
    rotate(deg) {
      if (this.$refs.cropper) {
        this.$refs.cropper.rotate += deg;
      }
    },

    zoom(percent) {
      if (this.$refs.cropper) {
        this.$refs.cropper.changeScale(percent);
      }
    },
    //提取裁剪后的图片
    async cropAndUpload() {
      try {
        if (!this.$refs.cropper || !this.$refs.cropper.getCropData) {
          throw new Error("裁剪组件未正确初始化");
        }

        this.isCropping = true;

        // 使用 getCropData 获取裁剪后的 base64 图片
        this.$refs.cropper.getCropData(async (base64Image) => {
          // 将 base64 转换为 Blob
          const blob = await fetch(base64Image).then(r => r.blob());

          const formData = new FormData();
          const ext = this.currentImage.minioName.split('.').pop() || 'png';
          const filename = `cropped_${Date.now()}.${ext}`;

          formData.append("id", this.currentImage.id);
          formData.append("file", new File([blob], filename, { type: blob.type }));
          formData.append("minioName", this.currentImage.minioName);

          const res = await this.$axios.post("/user/minio/userUploadImage", formData, {
            timeout: 300000
          });

          if (res.data.code !== 1) throw new Error(res.data.msg || "服务器错误");

          const index = this.images.findIndex(i => i.id === this.currentImage.id);
          if (index > -1) {
            this.$set(this.images, index, {
              ...res.data.data,
              _version: Date.now()
            });
          }

          this.$message.success("图片更新成功");
          this.cropperVisible = false;
        });

      } catch (error) {
        console.error('裁剪失败:', error);
        this.$message.error(`操作失败: ${error.message}`);
        if (this.originalImage) {
          const index = this.images.findIndex(i => i.id === this.originalImage.id);
          if (index > -1) this.$set(this.images, index, this.originalImage);
        }
      } finally {
        this.isCropping = false;
      }
    },

    async handleFileChange(e) {
      const MAX_SIZE = 1024 * 1024 * 1024; // 1GB
      const files = Array.from(e.target.files).filter(file => {
        if (file.size > MAX_SIZE) {
          this.$message.error(`${file.name} 超过1GB限制`);
          return false;
        }
        return true;
      });

      for (const file of files) {
        try {
          const formData = new FormData();
          formData.append('file', file);
          formData.append('verificationId', this.verificationId || '');

          const res = await this.$axios.post('/user/minio/userUploadImage', formData, {
            timeout: 300000
          });

          if (res.data.code !== 1) throw new Error(res.data.msg);
          this.images.push(res.data.data);
          this.$message.success(`${file.name} 上传成功`);
        } catch (error) {
          this.$message.error(`${file.name} 上传失败: ${error.message}`);
        }
      }
    },

    // 提交验证码
    async submitCode() {
      try {
        const res = await this.$axios.get(`/user/verification/imageUpload/${this.code}`);
        if (res.data.code !== 1) throw new Error(res.data.msg);

        const { id, expireAt, imageList } = res.data.data;
        this.verificationId = id;
        this.expireAt = expireAt;
        this.isVerified = true;
        if (Array.isArray(imageList)) {
          this.images.push(...imageList);
        }

        this.$message.success("验证码正确");
      } catch (e) {
        this.$message.error("验证码错误：" + e.message);
      }
    },
    // 提交订单
    async submitOrder() {
      try {
        const res = await this.$axios.post('/user/order/createOrder', {
          imageIdList: this.images.map(img => img.id),
          verificationId: this.verificationId || null
        });

        if (res.data.code !== 1) throw new Error(res.data.msg);
        this.$message.success("提交成功");
        this.resetForm();
      } catch (e) {
        this.$message.error("提交失败：" + e.message);
      }
    },

    // 重置表单
    resetForm() {
      this.images = [];
      this.verificationId = null;
      this.expireAt = null;
      this.isVerified = false;
      this.code = '';
    },
    handleDialogClosed() {
      if (this.cropperImageSrc) {
        URL.revokeObjectURL(this.cropperImageSrc);
      }
      this.cropperImageSrc = null;
      this.originalImage = null;
      // 清除其他相关状态
      this.currentImage = null;
    },
    // 增强的弹窗打开处理
    handleDialogOpened() {
      this.$nextTick(() => {
        const cropper = this.$refs.cropper;

        if (!cropper) {
          this.$message.error('裁剪组件未加载');
          return;
        }

        // 使用 $once 确保事件仅被监听一次
        cropper.$once('imgLoad', () => {
          console.log('VueCropper 图片加载完成');
          this.initCropper();
        });

        // 如果图片加载超时，则提示用户
        setTimeout(() => {
          if (!cropper.img) {
            console.error('图片加载超时');
            this.$message.error('图片加载超时，请重试');
            this.cropperVisible = false;
          }
        }, 5000);

        // 强制重新加载图片
        if (this.cropperImageSrc) {
          cropper.replace(this.cropperImageSrc);
        } else {
          console.warn('没有有效的图片源');
        }
      });
    },
    deleteImage(img) {
        this.$confirm('确定要删除这张图片吗？', '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
        }).then(() => {
            // 调用删除图片的API
            this.$axios.delete(`/user/minio/deleteImage/${img.id}`)
                .then(response => {
                    if (response.data.code === 1) {
                        const index = this.images.findIndex(i => i.id == img.id);
                        if (index > -1) {
                            this.images.splice(index, 1);
                        }
                        this.$message.success('删除成功');
                    } else {
                        this.$message.error(`删除失败: ${response.data.msg}`);
                    }
                })
                .catch(error => {
                    console.error('请求失败:', error);
                    this.$message.error('操作失败，请稍后再试');
                });
        }).catch(() => {
            // 取消删除操作
        });
    },
  },
  created() {
    this.$axios = axios.create({
      baseURL: '/api',
      withCredentials: true,
      timeout: 300000
    });

    this.isMobile = window.innerWidth <= 768;
    window.addEventListener('resize', () => {
      this.isMobile = window.innerWidth <= 768;
    });
  },
};
</script>

<style scoped>
.upload-page {
  position: relative;
  padding: 20px;
  justify-content: center;
}

.verify-section {
  text-align: center;
  margin-top: 50px;
}

.verified-content {
  width: 100%;
  max-width: 1200px;
  margin: 0 auto;
}

.expire-time {
  font-size: 14px;
  color: #666;
  background: #f5f7fa;
  padding: 6px 12px;
  border-radius: 4px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
  margin-bottom: 20px;
  display: inline-block;
}

.button-group {
  float: right;
  margin-bottom: 20px;
}

.image-list-container {
  display: flex;
  justify-content: center;
  align-items: stretch;
  width: 100%;
  clear: both;
}

.image-list {
  width: 100%;
  max-width: 1200px;
  margin: 0 auto;
}

.image-col {
  display: flex;
  justify-content: center;
  align-items: center;
}

.image-item {
  width: 100%;
  padding: 10px;
  box-sizing: border-box;
  text-align: center;
  background-color: #fff;
  border: 1px solid #ddd;
  border-radius: 8px;
  transition: all 0.2s ease;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.image-item:hover {
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}

.preview-img {
  width: 100%;
  height: 200px; /* 固定高度 */
  object-fit: cover;
  border-radius: 8px;
  margin-bottom: 10px;
}

.button-group {
  display: flex;
  justify-content: space-between;
  width: 100%;
  margin-top: 8px;
}

@media (min-width: 769px) {
  .el-col-md-8,
  .el-col-lg-6,
  .el-col-xl-6 {
    flex-basis: calc(25% - 20px); /* 每行4张图片，减去间距 */
    max-width: calc(25% - 20px);
  }
}

@media (max-width: 768px) {
  .el-col-xs-24,
  .el-col-sm-12 {
    flex-basis: 100%; /* 每行1张或2张图片 */
    max-width: 100%;
  }

  .button-group {
    float: none;
    text-align: right;
    flex-direction: column;
  }

  .button-group .el-button {
    width: 100%;
    margin-left: 0;
    margin-top: 5px;
  }
}

.placeholder {
  visibility: hidden; /* 使用占位符来填充网格但不显示内容 */
}

.empty-container {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 400px; 
}

/* 裁剪容器样式 */
.cropper-container {
  width: 100%;
  height: 60vh;
  min-height: 400px;
  position: relative;
}

::v-deep .cropper-container {
  background: #f8f9fa;
  border-radius: 4px;
}

::v-deep .cropper-view-box {
  outline: 2px solid #409EFF !important;
  box-shadow: 0 0 5px rgba(64, 158, 255, 0.3);
}

::v-deep .cropper-dashed {
  border-color: rgba(64, 158, 255, 0.2);
}

::v-deep .cropper-point {
  background-color: #409EFF;
  width: 10px;
  height: 10px;
  opacity: 0.9;
}

/* 新增裁剪窗口样式 */
.cropper-wrapper {
  width: 100%;
  height: 60vh;
  min-height: 400px;
  background: #f8f9fa;
  border-radius: 4px;
}

::v-deep .vue-cropper {
  border-radius: 4px;
  overflow: hidden;
}

/* 强制指定裁剪容器尺寸 */
.cropper-container {
  width: 100% !important;
  height: 60vh !important;
  min-height: 400px !important;
}

/* 修复移动端触控 */
.cropper-container img {
  touch-action: none;
}

@media (max-width: 768px) {
  /* 移动端裁剪容器高度调整 */
  .cropper-container {
    height: 50vh;
  }

  ::v-deep .cropper-point {
    width: 14px;
    height: 14px;
  }
}
.dialog-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 15px 20px;
}

@media (max-width: 768px) {
  .dialog-footer {
    flex-direction: column;
    align-items: flex-start;
    gap: 10px;
  }
    /* 移动端按钮样式调整 */
  .dialog-footer .el-button, 
  .dialog-footer .el-button-group .el-button {
    padding: 8px 12px; /* 减少内边距 */
    font-size: 15px; /* 减小字体大小 */
    min-width: auto; /* 可选：如果需要更紧凑的布局 */
  }
}
</style>